package com.fare.taluo.core.domain.queue.warn;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.mail.MessagingException;
import javax.persistence.Column;
import javax.persistence.Table;

import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.foreveross.hbase.client.HBaseHelper;
import org.foreveross.hbase.client.HBasePlaneinfoHelper;
import org.hibernate.annotations.Where;

import com.dayatang.domain.InstanceFactory;
import com.fare.taluo.GlobalsConst;
import com.fare.taluo.auth.domain.UserInfoEntity;
import com.fare.taluo.core.domain.analyse.alert.FreightPriceAnalyseAlertConfigEntity;
import com.fare.taluo.core.domain.config.channel.SourceEntity;
import com.fare.taluo.core.domain.config.channel.SourceEntityRepository;
import com.fare.taluo.core.domain.freightprice.FreightPriceRepository;
import com.fare.taluo.core.domain.queue.QueueBaseEntity;
import com.fare.taluo.core.domain.queue.QueueBaseRepository;
import com.fare.taluo.core.domain.queue.message.MessageCreatorFactory;
import com.fare.taluo.core.domain.queue.message.QueueEmailMessageEntity;
import com.fare.taluo.core.domain.queue.message.QueueSMSMessageEntity;
import com.fare.taluo.core.domain.queue.warn.repository.QueueFreightPriceWarnReposity;
import com.fare.taluo.fetl.domain.entity.FreightMontiorEntity;
import com.fare.taluo.fetl.domain.entity.FreightPriceEntity;
import com.fare.taluo.vo.core.PlaneInfo;
import com.foreveross.threadpool.queue.WorkQueue;

/**
 * 运价对比预警队列
 * <p>
 * 主要任务: 1、根据配置的预警机制，在指定时间段内，循环判断是否符合预警条件 2、若符合条件，则产生消息提醒队列，邮件或短信通知用户
 * 
 * @author creator: xiangsf
 * @author modifior: xiangsf
 * @since 2012-12-11 下午1:51:22
 * @version v1.0
 */
@javax.persistence.Entity
@Table(name = "QUE_FREIGHT_PRICE_WARN")
@Where(clause = "flg_deleted=0")
public class QueueFreightPriceWarnEntity extends
		QueueBaseEntity<QueueFreightPriceWarnEntity>{

	/**
	 * 
	 */
	private static final long serialVersionUID = 6198181325976208123L;
	/**
	 * 配置项的ID
	 */
	@Column(name = "DELEGATE_ID")
	private Long delegateId;
	/**
	 * 邮件发送目标地址
	 */
	@Column(name = "EMAIL_ADDRESS")
	private String emailAddress;
	/**
	 * 短信发送目标地址
	 */
	@Column(name = "SMS_ADDRESS")
	private String smsAddress;
	/**
	 * 配置项的实际参数集合，以KEY=VALUE形式存储
	 */
	@Column(name = "DELEGATE_PARAMS")
	private String delegateParams;

	@Override
	protected QueueBaseRepository<QueueFreightPriceWarnEntity> getEntityRepository() {
		return InstanceFactory.getInstance(QueueFreightPriceWarnReposity.class);
	}

	@Override
	public QueueFreightPriceWarnEntity createNextTask(Long id) throws Exception {
		// 根据id获得对象
		QueueFreightPriceWarnEntity entity = super.getBaseEntityRepository().get(
				QueueFreightPriceWarnEntity.class, id);

		// 没有邮件与短信地址，也不再创建对象了，暂不再从UserInfo中去拿这个地址
		if (StringUtils.isEmpty(entity.getSmsAddress())
				&& StringUtils.isEmpty(entity.getEmailAddress())) {
			return null;
		}
		// 获得配置项，配置项不存在，返回
		if (entity.getDelegateId() == null)
			return null;

		FreightPriceAnalyseAlertConfigEntity config = super.getBaseEntityRepository()
				.get(FreightPriceAnalyseAlertConfigEntity.class,
						entity.getDelegateId());
		if (config == null)
			return null;
		// 邮件与短信，预警方式都没有启用则，不用产生下一周期数据了。
		if (!config.isEmail() && !config.isSms()) {
			return null;
		}
		// 判断配置项的预警结束时间是否已超出当前时间，若超出，则返回
		if (config.getEndTime()!=null && config.getEndTime().before(new Date()))
			return null;
		// 产生在配置项上配置的频率的下一周期预警任务
		int frequency = config.getAlertFrequency();// 单位是小时
		QueueFreightPriceWarnEntity newEntity = new QueueFreightPriceWarnEntity();
		newEntity.setCreateTime(new Date());
		newEntity.setCreator(entity.getCreator());
		newEntity.setCreatorName(entity.getCreatorName());
		newEntity.setDelegateId(entity.getDelegateId());
		newEntity.setDelegateParams(entity.getDelegateParams());
		newEntity.setEmailAddress(entity.getEmailAddress());
		newEntity.setFlgDeleted(GlobalsConst.FLG_NO);
		if (entity.getName().startsWith("(自动频率创建)")) {
			newEntity.setName(entity.getName());
		} else {
			newEntity.setName("(自动频率创建)" + entity.getName());
		}
		newEntity.setSmsAddress(entity.getSmsAddress());
		newEntity.setStatus(WorkQueue.STATUS_WAITING);
		//newEntity.setStartTime(entity.getStartTime());
		//newEntity.setEndTime(entity.getEndTime());
		// 根据频率设置下一个任务的计划开始时间
		newEntity.setPlanStartTime(DateUtils.addHours(
				entity.getPlanStartTime(), frequency));
		if (newEntity.getPlanStartTime().before(new Date())) {
			newEntity.setPlanStartTime(DateUtils
					.addHours(new Date(), frequency));
		}
		super.getBaseEntityRepository().save(newEntity);
		return newEntity;
	}

	// @Override
	// public void executeTask(Long id) throws Exception{
	// QueueFreightPriceWarnEntity entity = this.doGet(id);
	// //预警的目标对象为空，直接返回
	// if(StringUtils.isEmpty(entity.getSmsAddress()) &&
	// StringUtils.isEmpty(entity.getEmailAddress())){
	// return;
	// }
	// //1、获得配置项，若配置项不存在，则不需要执行，直接返回
	// FreightPriceAnalyseAlertConfigEntity config =
	// super.getBaseEntityRepository().get(FreightPriceAnalyseAlertConfigEntity.class,
	// entity.getDelegateId());
	//
	// if(config == null) return;
	//
	// //2、判断配置项的预警结束时间是否已超出当前时间，若超出，则返回
	// if(config.getEndTime().before(new Date())) return;
	// //两个提醒功能都 没有开启，则不进行预警
	// if(!config.isEmail() && !config.isSms()) return;
	// //3、配置项上有航段，差价比，根据航段查询出当天的南航最低价与外航最低，得出低于差价比的外航价，并将网站名，价格等记录入集合
	// //查询出航段的，各航空公司最低价
	// List<FreightFlightEntity> list =
	// getFreightPriceRepository().findDay(config.getFromCity(),
	// config.getToCity(), new Date());
	//
	// if(list == null || list.isEmpty()) return;
	// //预警策略
	// FreightPriceWarnStrategy strategy = new FreightPriceWarnStrategy(config);
	// List<FreightPriceAlertVO> alertVos = strategy.getAlertVO(list);
	// //4、如果没有符合差价比的集合，则返回，否则创建邮件（或短信），邮件/短信计划发送时间为当前时间
	// //邮件内容为需求中表格，主题为“竞争对手运价预警 YYYY-MM-DD”
	// if(alertVos != null && !alertVos.isEmpty()){
	// if(config.isEmail() && StringUtils.isNotEmpty(entity.getEmailAddress())){
	// QueueEmailMessageEntity email =
	// MessageCreatorFactory.createEmailQueue(String.format("竞争对手运价预警 %s",
	// DateFormatUtils.format(new Date(),
	// "yyyy-MM-dd")),strategy.buildEmailContent1(alertVos),emailAddress,new
	// Date());
	// super.getBaseEntityRepository().save(email);
	// }
	// if(config.isSms() && StringUtils.isNotEmpty(entity.getSmsAddress())){
	// QueueSMSMessageEntity sms =
	// MessageCreatorFactory.createSMSQueue(smsAddress,
	// String.format("竞争对手运价预警 %s,详细信息请查阅邮件.",
	// DateFormatUtils.format(new Date(), "yyyy-MM-dd")),new Date());
	// super.getBaseEntityRepository().save(sms);
	// }
	// }
	// }
	//

	@Override
	public void executeTask(Long id) throws Exception {
		QueueFreightPriceWarnEntity entity = this.doGet(id);
		Long delegateId = entity.getDelegateId();
		FreightPriceAnalyseAlertConfigEntity freightPriceConfigEntity = null;
		Integer alertType = null;
		try {
			freightPriceConfigEntity = this.getFreightPriceAlertConfigEntity(delegateId);
			 alertType = freightPriceConfigEntity.getAlertType();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		// 预警的目标对象为空，直接返回
		if (StringUtils.isEmpty(entity.getSmsAddress())
				&& StringUtils.isEmpty(entity.getEmailAddress())) {
			return;
		}
		// 1、获得配置项，若配置项不存在，则不需要执行，直接返回
		FreightPriceAnalyseAlertConfigEntity config = super.getBaseEntityRepository()
				.get(FreightPriceAnalyseAlertConfigEntity.class,
						entity.getDelegateId());

		if (config == null)
			return;

		
		// 2、判断配置项的预警结束时间是否已超出当前时间，若超出，则返回
		//因为时间上，配置的结束时间没有到时分秒，这样导致该判断不包括结束时间的当天，所以这里加一天
		if(config.getEndTime()!=null){
			if (DateUtils.addDays(config.getEndTime(), 1).before(new Date()))
				return;
		}
	
		// 两个提醒功能都 没有开启，则不进行预警
		if (!config.isEmail() && !config.isSms())
			return;
		
		//3、获得当前用户所属航空公司
		UserInfoEntity currentUser = super.getBaseEntityRepository().get(UserInfoEntity.class, entity.getCreator());
		Long channelId = currentUser.getSourceId();
		
		//4、如果当前用户没有所属渠道，则不进行预警
		if(channelId == null) return ;
		
		SourceEntity currentUserSource = InstanceFactory.getInstance(SourceEntityRepository.class)
				.findByHbaseKey(channelId+"");
		if(currentUserSource == null) return ;
		//String currentHbaseKey = currentUserSource.getHbaseKey();
		
		
		if(alertType.equals(GlobalsConst.ALERT_TYPE_LOWEST_PRICE)){
			//最低价预警
			this.startFreightPriceAlert(config,currentUserSource,entity);
		}else if(alertType.equals(GlobalsConst.ALERT_TYPE_CABIN_CHANGE)){
			//舱位变动预警
			this.startCabinChangeAlert(config, currentUserSource, entity);
		}else if(alertType.equals(GlobalsConst.ALERT_TYPE_STREAD)){
			//价差预警
			this.startSpreadAlert(config, currentUserSource, entity);
		}else if(alertType.equals(GlobalsConst.ALERT_TYPE_COMPETE_CONTRAST)){
			//竞争对比预警
			this.startCompeteContrastAlert(config, currentUserSource, entity);
		}
		
		
		
		/*//5、 获取所有渠道
		List<SourceEntity> sourceList = InstanceFactory.getInstance(SourceEntityRepository.class).findAllSourceEntity();
		List<String> hbasekeys = new ArrayList<String>();
		for(SourceEntity s : sourceList){
			hbasekeys.add(s.getHbaseKey());
		}
		//查询出所有渠道指定时间内的所有抓取到的价格，对应hbase表为LP_LINE_DAY
		Map<String, Map<String, List<PlaneInfo>>> map = this.getLineDayLowerPrices(config, hbasekeys);
		
		//拿出当前用户所属渠道价格，与其它渠道对比
		int count = 0;

		List<PlaneInfo> saveContent = new ArrayList<PlaneInfo>();
		PlaneInfo currentPlaneInfo = null;
		List<PlaneInfo> tempList = null;
		PlaneInfo lowerPlaneInfo = null;
		String day = null;
		for (int i = 0; i < config.getFutureDays(); i++) {
			Calendar cal = Calendar.getInstance();// 使用默认时区和语言环境获得一个日历
			cal.add(Calendar.DATE, i);// 取当前日期的后的 未来几天.
			day = DateFormatUtils.format(cal.getTime(), "yyyy-MM-dd");
			//当前用户所属渠道价格
			tempList = map.get(currentUserSource.getHbaseKey()) != null ? map.get(currentUserSource.getHbaseKey()).get(day) : null;
			//如果没有 这一天的，则过滤掉
			if(tempList == null || tempList.isEmpty()) continue;
			
			currentPlaneInfo = this.getLowerPrices(tempList);
			//获得其它渠道当前日期最低价集合
			tempList = this.getOtherChannelLowerPrices(currentHbaseKey, day, hbasekeys, map);
			//没有其它渠道比较
			if(tempList == null || tempList.isEmpty()) continue;
			//获得其它所有渠道比当前用户所属渠道还要低的价格
			lowerPlaneInfo = this.getAnalogyLowerPrices(currentPlaneInfo, tempList);
			
			//将某一天，符合某航空公司的最低计数
			if(lowerPlaneInfo != null){
				count ++; //每累加一次，就代表有一天比当前渠道价格少
				saveContent.add(lowerPlaneInfo);
			}
		}
		//不符合配置天数据，一定要大于触发条件才发邮件
		if (count < config.getTriggerCondition()) 
			return;
		//如果少的（暂不考虑高的）
		if (saveContent == null || saveContent.isEmpty())
			return;

		// 预警策略
		FreightPriceWarnStrategy strategy = new FreightPriceWarnStrategy(config);

				if (config.isEmail()
						&& StringUtils.isNotEmpty(entity.getEmailAddress())) {
					QueueEmailMessageEntity email = MessageCreatorFactory
							.createEmailQueue(String.format("最低价运价 %s",
									DateFormatUtils.format(new Date(),
											"yyyy-MM-dd hh:mm")), strategy
									.buildEmailContent3(saveContent),
									entity.getEmailAddress().trim(), new Date());
					super.getBaseEntityRepository().save(email);
				}

				if (config.isSms()
						&& StringUtils.isNotEmpty(entity.getSmsAddress())) {
					QueueSMSMessageEntity sms = MessageCreatorFactory
							.createSMSQueue(entity.getSmsAddress().trim(), String.format(
									"最低价运价 %s,详细信息请查阅邮件.", DateFormatUtils
											.format(new Date(),
													"yyyy-MM-dd hh:mm")),
									new Date());
					super.getBaseEntityRepository().save(sms);
				}*/
	}
	
	public void startCompeteContrastAlert(FreightPriceAnalyseAlertConfigEntity config,SourceEntity currentUserSource,QueueFreightPriceWarnEntity entity) throws MessagingException{
		boolean isCompeteContrastChange = false;
		List<FreightPriceEntity> list  = isCompeteContrastChange(config,currentUserSource,entity);
		if(list != null){
			CompeteContrastWarnStrategy strategy = new CompeteContrastWarnStrategy(config,list);
			if (config.isEmail() && StringUtils.isNotEmpty(entity.getEmailAddress())) {
				QueueEmailMessageEntity email = 
			MessageCreatorFactory.createEmailQueue(
					String.format("竞争对比预警 %s",
					DateFormatUtils.format(new Date(),"yyyy-MM-dd hh:mm")),
					strategy.buildEmailContent(),
					entity.getEmailAddress().trim(), 
					new Date()
			);
			super.getBaseEntityRepository().save(email);
			}

			if (config.isSms()
					&& StringUtils.isNotEmpty(entity.getSmsAddress())) {
				QueueSMSMessageEntity sms = MessageCreatorFactory
						.createSMSQueue(entity.getSmsAddress().trim(),
								String.format("竞争对比预警%s,详细信息请查阅邮件.",
										DateFormatUtils.format(new Date(),
												"yyyy-MM-dd hh:mm")),
								new Date());
				super.getBaseEntityRepository().save(sms);
			}
		}
		
		
		
	}
	
	private List<FreightPriceEntity> isCompeteContrastChange(FreightPriceAnalyseAlertConfigEntity config,SourceEntity currentUserSource,QueueFreightPriceWarnEntity entity){
		FreightPriceEntity competeContrastEntity = null;
		FreightPriceEntity competeContrastTemp = new FreightPriceEntity();
		//获得查询条件
		String fromCity = config.getFromCity();
		String toCity = config.getToCity();
		String grabChannelKey = config.getCarrierKey();//承运公司
		String flightNo = config.getFlightNo();
		Date flightDate = config.getFlightDate();// com.fare.taluo.util.DateUtils.dateToStr(config.getFlightDate(), "yyyy-MM-dd");
		String cabinLevel = config.getCabinLevel();//默认为经济舱最低价与渠道的最低价比较
		
		String contrastCompanyKey = config.getContrastSourceKey();
		String contrastFlightNo = config.getContrastFlightNo();
		String contrastCabinLevel = config.getContrastCabinLevel();
		Integer trigger = config.getTriggerCondition();
		Integer futureDays = config.getFutureDays();//连续天数
		Date createTime = config.getCreateTime();
		Date planStartDate = entity.getPlanStartTime();
		//若航班日期比系统时间要早则过了预警时间，不进行预警
		if(flightDate.getTime()<new Date().getTime()){
			return null;
		}
		
		List<FreightPriceEntity> findList = competeContrastTemp.findByConditionContrast(fromCity,toCity,grabChannelKey,flightNo,flightDate,cabinLevel,contrastCompanyKey,contrastFlightNo,contrastCabinLevel, planStartDate,futureDays);
	    int triggerCondition = 0;
	    if(findList.size()>0){
	    	//比对比的航空公司价格低
	    	if(trigger == 0){
	    		
	    		
	    		
	    		 for (int i = 0;i < findList.size(); i++) {
	 			    FreightPriceEntity compareEntity = findList.get(i);
	 				if(compareEntity!= null &&(compareEntity.getPrice()!=null && compareEntity.getComparePrice()!=null) && compareEntity.getPrice() < compareEntity.getComparePrice()){
	 					int betweenDay = this.daysBetween(compareEntity.getGrabDate(), entity.getPlanStartTime());
	 		    		if(betweenDay == i+1){
	 						triggerCondition += 1;
	 						if(triggerCondition >= futureDays){
	 							return findList;
	 						}
	 		    		}else{
	 		    			return null;
	 		    		}
	 				
	 				}else{
	 					return null;
	 				}
	 	    	
	 		   }
	    		//比对比的航空公司价格高
	    	}else if(trigger == 1){
	    		 for (int i = 0;i < findList.size(); i++) {
		 			    FreightPriceEntity compareEntity = findList.get(i);
		 				if(compareEntity!= null &&(compareEntity.getPrice()!=null && compareEntity.getComparePrice()!=null) && compareEntity.getPrice() > compareEntity.getComparePrice()){
		 					int betweenDay = this.daysBetween(compareEntity.getGrabDate(), entity.getPlanStartTime());
		 		    		if(betweenDay == i+1){
		 						triggerCondition += 1;
		 						if(triggerCondition >= futureDays){
		 							return findList;
		 						}
		 		    		}else{
		 		    			return null;
		 		    		}
		 				
		 				}else{
		 					return null;
		 				}
		 	    	
		 		   }
	    	}
		    
		    	
	    }
		return null;
	    		
		
	}
	
	public void startSpreadAlert(FreightPriceAnalyseAlertConfigEntity config,SourceEntity currentUserSource,QueueFreightPriceWarnEntity entity) throws MessagingException{
		boolean isSpreadChange = false;
		List<FreightPriceEntity> list = isSpreadChange(config,currentUserSource,entity);
		if(list != null){
			SpreadWarnStrategy strategy = new SpreadWarnStrategy(config,list);
			if (config.isEmail() && StringUtils.isNotEmpty(entity.getEmailAddress())) {
				QueueEmailMessageEntity email = 
			MessageCreatorFactory.createEmailQueue(
					String.format("价差变动 %s",
					DateFormatUtils.format(new Date(),"yyyy-MM-dd hh:mm")),
					strategy.buildEmailContent(),
					entity.getEmailAddress().trim(), 
					new Date()
			);
			super.getBaseEntityRepository().save(email);
			}

			if (config.isSms()
					&& StringUtils.isNotEmpty(entity.getSmsAddress())) {
				QueueSMSMessageEntity sms = MessageCreatorFactory
						.createSMSQueue(entity.getSmsAddress().trim(),
								String.format("价差变动 %s,详细信息请查阅邮件.",
										DateFormatUtils.format(new Date(),
												"yyyy-MM-dd hh:mm")),
								new Date());
				super.getBaseEntityRepository().save(sms);
			}
		}
		
		
		
		
		
		
	}
	public static void main(String[] args) {
		System.out.println(new Integer(1)==1);
	}
	
	private  List<FreightPriceEntity>  isSpreadChange(FreightPriceAnalyseAlertConfigEntity config,SourceEntity currentUserSource,QueueFreightPriceWarnEntity entity){
		FreightPriceEntity spreadChangeEntity = null;
		FreightPriceEntity spreadChangeTemp = new FreightPriceEntity();
		//获得查询条件
		String fromCity = config.getFromCity();
		String toCity = config.getToCity();
		String grabChannelKey = config.getCarrierKey();//承运公司
		String flightNo = config.getFlightNo();
		Date flightDate =config.getFlightDate();// com.fare.taluo.util.DateUtils.dateToStr(config.getFlightDate(), "yyyy-MM-dd");
		String contrastSourceKey = config.getContrastSourceKey();//对比渠道
		String cabinLevel = config.getCabinLevel();//默认为经济舱最低价与渠道的最低价比较
		Integer continueDays = config.getTriggerCondition();//连续天数
		Integer spreadRadio =config.getTriggerConditionSpread();
		Date createTime = config.getCreateTime();
		Date planStartTime = entity.getPlanStartTime();
		//用来保存发送内容
		List<List<FreightPriceEntity>> listList = new ArrayList<List<FreightPriceEntity>>();
	    List<FreightPriceEntity> findList =  spreadChangeTemp.findByConditionSpread(fromCity,toCity,grabChannelKey,flightNo,flightDate,contrastSourceKey,planStartTime,continueDays);
	    int triggerCondition =0;
	    if(findList.size()>0){
	    	 //触发分两种情况，1若配置的价差是正数，则预处理的价差要大于正数价差
		    //			 2若配置的价差是负数，则预处理的价差要小于负数价差
	    	 if(spreadRadio > 0){
	    		 for (int i = 0; i < findList.size(); i++) {
					    FreightPriceEntity spreadEntity = findList.get(i);
					    //若价差满足，触发条件加1,大于或等于设置条件则触发预警
					   
					    	if(spreadEntity != null && spreadEntity.getPriceRatio()!=null &&spreadEntity.getPriceRatio()*100 > spreadRadio){
					    		int betweenDay = this.daysBetween(spreadEntity.getGrabDate(), entity.getPlanStartTime());
					    		if(betweenDay == i+1){
					    			triggerCondition += 1;
									if(triggerCondition >= continueDays){
										return findList;
									}
					    		}else{
					    			//记录抓取时间不是在航班日期之前则不符合预警条件，如航班日期是9月10号，最近抓取日期是8号则不符合连续天数这个条件
					    			return null;
					    		}
								
							}else{
								return null;
							}
					    }
			
		    	
			   }else if(spreadRadio < 0){
				   for (int i = 0; i < findList.size(); i++) {
					    FreightPriceEntity spreadEntity = findList.get(i);
					    //若价差满足，触发条件加1,大于或等于设置条件则触发预警
					   
					    	if(spreadEntity != null && spreadEntity.getPriceRatio()!=null &&spreadEntity.getPriceRatio()*100 < spreadRadio){
					    		int betweenDay = this.daysBetween(spreadEntity.getGrabDate(), entity.getPlanStartTime());
					    		if(betweenDay == i+1){
					    			triggerCondition += 1;
									if(triggerCondition >= continueDays){
										return findList;
									}
					    		}else{
					    			//记录抓取时间不是在航班日期之前则不符合预警条件，如航班日期是9月10号，最近抓取日期是8号则不符合连续天数这个条件
					    			return null;
					    		}
								
							}else{
								return null;
							}
					    }
			   }
			    	
		    }
			return null;
	}
	
	public void startCabinChangeAlert(FreightPriceAnalyseAlertConfigEntity config,SourceEntity currentUserSource,QueueFreightPriceWarnEntity entity) throws MessagingException{
		//根据方法返回的boolean值来判断是否需要进行预警
 		boolean isCountOrTypeChange = false;
 		List<FreightMontiorEntity> subList = null;
 		subList = isCabinChange(config,currentUserSource,entity);
		if(subList != null){
			CabinChangeWarnStrategy strategy = new CabinChangeWarnStrategy(config,subList);
			if (config.isEmail() && StringUtils.isNotEmpty(entity.getEmailAddress())) {
				QueueEmailMessageEntity email = 
			MessageCreatorFactory.createEmailQueue(
					String.format("舱位变动 %s",
					DateFormatUtils.format(new Date(),"yyyy-MM-dd hh:mm")),
					strategy.buildEmailContent(),
					entity.getEmailAddress().trim(), 
					new Date()
			);
			super.getBaseEntityRepository().save(email);
			}

			if (config.isSms()
					&& StringUtils.isNotEmpty(entity.getSmsAddress())) {
				QueueSMSMessageEntity sms = MessageCreatorFactory
						.createSMSQueue(entity.getSmsAddress().trim(),
								String.format("舱位变动 %s,详细信息请查阅邮件.",
										DateFormatUtils.format(new Date(),
												"yyyy-MM-dd hh:mm")),
								new Date());
				super.getBaseEntityRepository().save(sms);
			}
		}
		
	}
	
	private List<FreightMontiorEntity> isCabinChange(FreightPriceAnalyseAlertConfigEntity config,SourceEntity currentUserSource,QueueFreightPriceWarnEntity entity){
		FreightMontiorEntity cabinChangeEntity = null;
		FreightMontiorEntity cabinChangeTemp = new FreightMontiorEntity();
		//获得查询条件
		String fromCity = config.getFromCity();
		String toCity = config.getToCity();
		String grabChannelKey = config.getCarrierKey();
		String flightNo = config.getFlightNo();
		String flightDate = com.fare.taluo.util.DateUtils.dateToStr(config.getFlightDate(), "yyyy-MM-dd");
		
		//若航班已起飞则不进行预警
		long grapTime =  new Date().getTime() - config.getFlightDate().getTime();
		if(grapTime > 0){
			return null;
		}
		//配置项对应的预处理表中的记录
		//update xiangsf 2013-09-28这个地方要优化，不需要返回这么多数据，只需要最后两条，太多数据占内存
		List<FreightMontiorEntity> list = cabinChangeTemp.findByConditions(2, fromCity, toCity, grabChannelKey, flightNo, flightDate);
		List<FreightMontiorEntity> subList = null;
		if(list!=null&&list.size()>0){
			cabinChangeEntity = list.get(list.size()-1);
		}else{
			return null;
		}
		
		//值为0则表示舱位不变化，不需要预警,否则进行预警
		//情况1：一次抓取该航班有7个舱位（对应7个价格），下次抓取时该航班有5个舱位（对应5个价格），即舱位发生了变化。
		//情况2：一次抓取该航班有5个舱位（A/B/C/D/E），下次抓取时该航班有5个舱位（A/B/C/P/Q），舱位也发生了变化。
		//情况3：目标航班第1次抓取时，不算舱位改变。
		//以上两种情况均由CabinNumForChange决定，值为0则两种情况均不变化
		if(list.size() <= 1 && cabinChangeEntity.getGrabNum() == 1){//第一次抓取则
			return null;
		}else if((cabinChangeEntity.getCabinNumForAdd() != 0 ||cabinChangeEntity.getCabinNumForDel() != 0)){
			if(list.size()>=2){
				subList = list.subList(0, 2);
			}
			return subList;	
		}	
		return null;
	}
	
	/*private boolean isTypeOfCabinChange(FreightPriceAnalyseAlertConfigEntity config,SourceEntity currentUserSource,QueueFreightPriceWarnEntity entity){
		return false;
	}*/
	public void startFreightPriceAlert(FreightPriceAnalyseAlertConfigEntity config,SourceEntity currentUserSource,QueueFreightPriceWarnEntity entity) throws IOException, MessagingException{
		//5、 获取所有渠道
				List<SourceEntity> sourceList = InstanceFactory.getInstance(SourceEntityRepository.class).findAllSourceEntity();
				List<String> hbasekeys = new ArrayList<String>();
				for(SourceEntity s : sourceList){
					hbasekeys.add(s.getHbaseKey());
				}
				//查询出所有渠道指定时间内的所有抓取到的价格，对应hbase表为LP_LINE_DAY
				Map<String, Map<String, List<PlaneInfo>>> map = this.getLineDayLowerPrices(config, hbasekeys);
				String currentHbaseKey = currentUserSource.getHbaseKey();
				//拿出当前用户所属渠道价格，与其它渠道对比
				int count = 0;

				List<PlaneInfo> saveContent = new ArrayList<PlaneInfo>();
				PlaneInfo currentPlaneInfo = null;
				List<PlaneInfo> tempList = null;
				PlaneInfo lowerPlaneInfo = null;
				PlaneInfo higherPlaneInfo = null;
				String day = null;
				String upOrDown = ""+config.getBookingType();
				for (int i = 0; i < config.getFutureDays(); i++) {
					Calendar cal = Calendar.getInstance();// 使用默认时区和语言环境获得一个日历
					cal.add(Calendar.DATE, i);// 取当前日期的后的 未来几天.
					day = DateFormatUtils.format(cal.getTime(), "yyyy-MM-dd");
					//当前用户所属渠道价格
					tempList = map.get(currentUserSource.getHbaseKey()) != null ? map.get(currentUserSource.getHbaseKey()).get(day) : null;
					//如果没有 这一天的，则过滤掉
					if(tempList == null || tempList.isEmpty()) continue;
					
					currentPlaneInfo = this.getLowerPrices(tempList);
					//获得其它渠道当前日期最低价集合
					tempList = this.getOtherChannelLowerPrices(currentHbaseKey, day, hbasekeys, map);
					//没有其它渠道比较
					if(tempList == null || tempList.isEmpty()) continue;
			/*		if("0".equals(upOrDown)){*/
						//获得其它所有渠道比当前用户所属渠道还要低的价格
						lowerPlaneInfo = this.getAnalogyLowerPrices(currentPlaneInfo, tempList);
						
						//将某一天，符合某航空公司的最低计数
						if(lowerPlaneInfo != null){
							count ++; //每累加一次，就代表有一天比当前渠道价格少
							saveContent.add(lowerPlaneInfo);
						}
				/*	}else if("1".equals(upOrDown)){
						//获得其它所有渠道比当前用户所属渠道还要高的价格
						//lowerPlaneInfo = this.getAnalogyLowerPrices(currentPlaneInfo, tempList);
						higherPlaneInfo = this.getAnalogyHigherPrices(currentPlaneInfo, tempList);
						//将某一天，符合某航空公司的最低计数
						if(higherPlaneInfo != null){
							count ++; //每累加一次，就代表有一天比当前渠道价格少
							saveContent.add(higherPlaneInfo);
						}
					}*/
					
					
				}
				//不符合配置天数据，一定要大于触发条件才发邮件
				if("0".equals(upOrDown)){
					if (count > config.getTriggerCondition()) 
						return;
				}
				if("1".equals(upOrDown)){
					if (count < config.getTriggerCondition()) 
						return;
				}
				//如果少的（暂不考虑高的）
				if (saveContent == null || saveContent.isEmpty())
					return;

				// 预警策略
				FreightPriceWarnStrategy strategy = new FreightPriceWarnStrategy(config);

						if (config.isEmail()
								&& StringUtils.isNotEmpty(entity.getEmailAddress())) {
							MessageCreatorFactory
									.createEmailQueue(String.format("最低价运价 %s",
											DateFormatUtils.format(new Date(),
													"yyyy-MM-dd hh:mm")), strategy
											.buildEmailContent3(saveContent),
											entity.getEmailAddress().trim(), new Date());
							
						}

						if (config.isSms()
								&& StringUtils.isNotEmpty(entity.getSmsAddress())) {
							QueueSMSMessageEntity sms = MessageCreatorFactory
									.createSMSQueue(entity.getSmsAddress().trim(), String.format(
											"最低价运价 %s,详细信息请查阅邮件.", DateFormatUtils
													.format(new Date(),
															"yyyy-MM-dd hh:mm")),
											new Date());
							super.getBaseEntityRepository().save(sms);
						}
	}
	/**
	 * 其它渠道指定日期的最低价集合
	 * @param hbaseKey
	 * @param day
	 * @param allHbaseKeys
	 * @param allInfos
	 * @return
	 */
	private List<PlaneInfo> getOtherChannelLowerPrices(String hbaseKey, String day, List<String> allHbaseKeys, Map<String, Map<String, List<PlaneInfo>>> allInfos){
		List<PlaneInfo> list = new ArrayList<PlaneInfo>();
		List<PlaneInfo> temps = null;
		for(String key : allHbaseKeys){
			if(key.equalsIgnoreCase(hbaseKey)) continue;
			temps = allInfos.get(key) != null ? allInfos.get(key).get(day) : null;
			if(temps != null) list.addAll(temps);
		}
		return list;
	}
	/**
	 * 在指定最低价集合中，获得他们中的最低价对象
	 * @param infos
	 * @return
	 */
	private PlaneInfo getLowerPrices(List<PlaneInfo> infos){
		PlaneInfo pi = null;
		for(PlaneInfo p : infos){
			if(pi == null) pi = p;
			
			if(Double.valueOf(p.getLowerPrice()) < Double.valueOf(pi.getLowerPrice())){
				pi = p;
			}
		}
		return pi;
	}
	/**
	 * 当前与其它类比，得出比当前价还要低的最最最低的一条记录
	 * @param currentPlaneInfo 当前渠道最低价对象
	 * @param all 所有渠道某一天的最低价集合
	 * @return
	 */
	private PlaneInfo getAnalogyLowerPrices(PlaneInfo currentPlaneInfo, List<PlaneInfo> all){
		PlaneInfo tempPi = null;
		for(PlaneInfo p : all){
			
			if(Double.valueOf(p.getLowerPrice()) < Double.valueOf(currentPlaneInfo.getLowerPrice())){
				
				if(tempPi == null) tempPi = p;
				//取最最最低的
				if(Double.valueOf(p.getLowerPrice()) < Double.valueOf(tempPi.getLowerPrice())){
					tempPi = p;
				}
			}
		}
		return tempPi;
	}
	
	private PlaneInfo getAnalogyHigherPrices(PlaneInfo currentPlaneInfo, List<PlaneInfo> all){
		PlaneInfo tempPi = null;
		for(PlaneInfo p : all){
			
			if(Double.valueOf(p.getLowerPrice()) > Double.valueOf(currentPlaneInfo.getLowerPrice())){
				
				if(tempPi == null) tempPi = p;
				//取最最最高的
				if(Double.valueOf(p.getLowerPrice()) > Double.valueOf(tempPi.getLowerPrice())){
					tempPi = p;
				}
			}
		}
		return tempPi;
	}
	
	/**
	 * 获得所有渠 道当天的最低价集合
	 * @param config
	 * @param sourceList
	 * @return Map key=渠道  value = key 日期  value 最低价对象
	 * @throws IOException
	 */
	private Map<String, Map<String, List<PlaneInfo>>> getLineDayLowerPrices(FreightPriceAnalyseAlertConfigEntity config, List<String> hbasekeys) throws IOException{
		String startKey = null;
		String endKey = null;
		ResultScanner scan = null;
		List<PlaneInfo>	list = null;
		Map<String, Map<String, List<PlaneInfo>>> allLineDayPrices = new HashMap<String, Map<String, List<PlaneInfo>>>();
		 Map<String, List<PlaneInfo>> tempMap = null;
		 List<PlaneInfo> tempList = null;
		try{
			for (String hkey : hbasekeys) {
				Calendar cal = Calendar.getInstance();// 使用默认时区和语言环境获得一个日历
				cal.add(Calendar.DATE, config.getFutureDays());// 取当前日期的后的
																		// 未来几天.
	
				// startKey||endKey 格式：00001 CAN PEK
				// 20130324(HBase_Key,出发编号,终点编号,航班日期)
				 startKey = hkey + config.getFromCity()
						+ config.getToCity()
						+ DateFormatUtils.format(new Date(), "yyyyMMdd");
				 endKey = hkey + config.getFromCity()
						+ config.getToCity()
						+ DateFormatUtils.format(cal.getTime(), "yyyyMMdd");
	
				 scan = HBaseHelper.getRecords("LP_LINE_DAY", startKey, endKey);
	
				// 一个渠道的一条航线 某天开始 统计的 一个list
			    list = HBasePlaneinfoHelper.transformHBaseResultToPlaneinfo(scan);
			  
			    tempMap = new HashMap<String , List<PlaneInfo>>();
			   // StringBuilder builder = new StringBuilder();
				for (PlaneInfo info : list) {
					if(tempMap.get(info.getFlightBatchDate()) != null){
						tempMap.get(info.getFlightBatchDate()).add(info);
					}else{
						tempList = new ArrayList<PlaneInfo>();
						tempList.add(info);
						tempMap.put(info.getFlightBatchDate(), tempList);
					}
					//builder.append(info.getCarrierName()+"====="+info.getFlightBatch()+"===="+info.getFlightBatchDate()+"===="+info.getLowerPrice()+"\n");
					
				}
				//FileUtils.writeStringToFile(new File("F:/temp/hbase/temp_line_day"+hkey+".txt"), builder.toString());
			  allLineDayPrices.put(hkey, tempMap);
			}
		}finally{
			 startKey = null;
			 endKey = null;
			 scan = null;
			 list = null;
			 tempMap = null;
			 tempList = null;
		}
		return allLineDayPrices;
	}
	
	public int daysBetween(Date early, Date late) { 
	     
        java.util.Calendar calst = java.util.Calendar.getInstance();   
        java.util.Calendar caled = java.util.Calendar.getInstance();   
        calst.setTime(early);   
         caled.setTime(late);   
         //设置时间为0时   
         calst.set(java.util.Calendar.HOUR_OF_DAY, 0);   
         calst.set(java.util.Calendar.MINUTE, 0);   
         calst.set(java.util.Calendar.SECOND, 0);   
         caled.set(java.util.Calendar.HOUR_OF_DAY, 0);   
         caled.set(java.util.Calendar.MINUTE, 0);   
         caled.set(java.util.Calendar.SECOND, 0);   
        //得到两个日期相差的天数   
         int days = ((int) (caled.getTime().getTime() / 1000) - (int) (calst   
                .getTime().getTime() / 1000)) / 3600 / 24;   
         
        return days;   
   }
	
	public QueueFreightPriceWarnEntity doGet(Long id) {
		return super.getBaseEntityRepository().get(QueueFreightPriceWarnEntity.class, id);
	}
    
	public FreightPriceAnalyseAlertConfigEntity getFreightPriceAlertConfigEntity(Long id){
		return super.getBaseEntityRepository().get(FreightPriceAnalyseAlertConfigEntity.class, id);
	}
	
	public Long getDelegateId() {
		return delegateId;
	}

	public void setDelegateId(Long delegateId) {
		this.delegateId = delegateId;
	}

	public String getDelegateParams() {
		return delegateParams;
	}

	public void setDelegateParams(String delegateParams) {
		this.delegateParams = delegateParams;
	}

	public String getEmailAddress() {
		return emailAddress;
	}

	public void setEmailAddress(String emailAddress) {
		this.emailAddress = emailAddress;
	}

	public String getSmsAddress() {
		return smsAddress;
	}

	public void setSmsAddress(String smsAddress) {
		this.smsAddress = smsAddress;
	}

	protected FreightPriceRepository getFreightPriceRepository() {
		return InstanceFactory.getInstance(FreightPriceRepository.class);
	}

}
